﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SmApiLibrary.datatypes;
using SmApiLibrary.helps;

namespace SmApiLibrary.libs
{
    public class WeiBoSina : IWeiBo
    {
        private const string WeibeesinaUrl = "http://api.t.sina.com.cn/";
        private const string PathVerify = "account/verify_credentials";
        private const string PathFriendsTimeline = "statuses/friends_timeline";
        private const string PathStatusUpdate = "statuses/update";

        public OAuthSina OAuth { get; set; }

        public bool IsEnabled
        {
            get
            {
                return !string.IsNullOrEmpty(OAuth.Token);
            }
        }

        public WeiBoSina()
        {
            if (OAuth == null)
            {
                OAuth = new OAuthSina();
            }
        }

        /// <summary>
        /// 获取当前微博账号的id
        /// </summary>
        /// <returns></returns>
        public string GetUserId()
        {
            return this.GetWeiBoUserInfo().id;
        }

        /// <summary>
        /// 获取当前微博账号信息
        /// </summary>
        /// <returns></returns>
        public SinaUser GetWeiBoUserInfo()
        {
            string url = "http://api.t.sina.com.cn/account/verify_credentials.json";
            string result = OAuth.OAuthWebRequest(Method.GET, url, null, null);

            return GetSinaUser(result);
        }

        private SinaUser GetSinaUser(string result)
        {
            SinaUser suer = JsonHelper.JsonDeserialize<SinaUser>(result);
            return suer;
        }

        //--------------------------------------------------------------
        // Private Methods
        //--------------------------------------------------------------
        #region PrivateMethods

        #endregion


        /// <summary>
        /// 发布一条微博信息
        /// </summary>
        /// <param name="sMessage">文字内容</param>
        /// <returns>未知</returns>
        public string AddWeiBo(string sMessage)
        {
            return OAuth.OAuthWebRequest(Method.POST,
                                                      WeibeesinaUrl + PathStatusUpdate + ".json",
                                                      "status=" + Utility.UrlEncode(sMessage), null);
        }

        /// <summary>
        /// 发布一条图片微博信息
        /// </summary>
        /// <param name="sMessage">文字内容</param>
        /// <param name="pictureFilename">图片文件路径</param>
        /// <returns>未知</returns>
        public string AddWeiBoPic(string sMessage, string pictureFilename)
        {
            string url = @"http://api.t.sina.com.cn/statuses/upload.json";
            return OAuth.OAuthWebRequest(Method.POST,
                                                      url,
                                                      "status=" + Utility.UrlEncode(sMessage),
                                                      pictureFilename);
        }

        #region 评论
        /// <summary>
        /// 根据ID评论一条微博
        /// </summary>
        /// <param name="id">微博ID</param>
        /// <param name="comment">评论</param>
        /// <returns></returns>
        public string Comment(string id, string comment)
        {
            string url = @"http://api.t.sina.com.cn/statuses/comment.json";
            string para = string.Format("id={0}&comment={1}", id, Utility.UrlEncode(comment));
            return OAuth.OAuthWebRequest(Method.POST, url, para, null);
        }

        /// <summary>
        /// 根据微博消息ID返回某条微博消息的评论列表 
        /// </summary>
        /// <param name="id">微博ID</param>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetComments(string id, int count, int page)
        {
            if (count <= 0)
                count = 20;
            else if (count > 200)
                count = 200;
            if (page <= 0) page = 1;
            string url = @"http://api.t.sina.com.cn/statuses/comments.json?" + string.Format("id={0}&count={1}&page={2}", id, count, page);

            return OAuth.OAuthWebRequest(Method.GET, url, null);
        }

        #endregion

        #region 转发

        /// <summary>
        /// 返回一条原创微博消息的最新n条转发微博消息。本接口无法对非原创微博进行查询。 
        /// </summary>
        /// <param name="id">微博ID</param>
        /// <param name="since_id">若指定此参数，则只返回ID比since_id大的记录（比since_id发表时间晚）</param>
        /// <param name="max">若指定此参数，则返回ID小于或等于max_id的记录</param>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetReposts(string id, Int64 since_id, Int64 max, int count, int page)
        {
            if (count <= 0)
                count = 20;
            else if (count > 200)
                count = 200;
            if (page <= 0) page = 1;
            string url = @"http://api.t.sina.com.cn/statuses/repost_timeline.json?";
            string para = string.Format("id={0}&count={1}&page={2}", id, count, page);
            if (since_id > 0)
                para += "&since_id=" + since_id;
            if (max > 0)
                para += "&max=" + max;
            return OAuth.OAuthWebRequest(Method.GET, url + para, null);
        }

        /// <summary>
        /// 返回一条原创微博消息的最新n条转发微博消息。本接口无法对非原创微博进行查询。 
        /// </summary>
        /// <param name="id">微博ID</param>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetReposts(string id, int count, int page)
        {
            return GetReposts(id, -1, -1, count, page);
        }

        /// <summary>
        /// 根据ID转发一条微博
        /// </summary>
        /// <param name="id">微博ID</param>
        /// <returns></returns>
        public string Repost(string id)
        {
            string url = @"http://api.t.sina.com.cn/statuses/repost.json";
            string para = string.Format("id={0}", id);
            return OAuth.OAuthWebRequest(Method.POST, url, para, null);
        }

        /// <summary>
        /// 根据ID转发并评论当前微博
        /// </summary>
        /// <param name="id">微博ID</param>
        /// <param name="status">转发文本</param>
        /// <returns></returns>
        public string Repost(string id, string status)
        {
            return this.Repost(id, status, 1);
        }

        /// <summary>
        /// 根据ID转发并评论一条微博,is_comment(是否在转发的同时发表评论0表示不发表评论，1表示发表评论给当前微博，2表示发表评论给原微博，3是1、2都发表。默认为0。)
        /// </summary>
        /// <param name="id">微博ID</param>
        /// <param name="status">转发文本</param>
        /// <param name="is_comment">是否在转发的同时发表评论。0表示不发表评论，1表示发表评论给当前微博，2表示发表评论给原微博，3是1、2都发表。默认为0。 </param>
        /// <returns></returns>
        public string Repost(string id, string status, int is_comment)
        {
            is_comment = Math.Max(is_comment, 0);
            is_comment = Math.Min(is_comment, 3);
            string url = @"http://api.t.sina.com.cn/statuses/repost.json";
            string para = string.Format("id={0}&status={1}&is_comment={2}", id, Utility.UrlEncode(status), is_comment);
            return OAuth.OAuthWebRequest(Method.POST, url, para, null);
        }

        #endregion

        /// <summary>
        /// 批量获取n条微博消息的评论数和转发数。一次请求最多可以获取20条微博消息的评论数和转发数
        /// </summary>
        /// <param name="ids">ID列表，用逗号隔开</param>
        /// <returns></returns>
        public string GetCounts(string ids)
        {
            string url = @"http://api.t.sina.com.cn/statuses/counts.json?ids=" + Utility.UrlEncode(ids);
            return OAuth.OAuthWebRequest(Method.GET, url, string.Empty);
        }

        #region  私信

        /// <summary>
        /// 返回登录用户的最新收到的n条私信，每条私信包含发送者和接受者的详细信息。
        /// </summary>
        /// <param name="since_id">若指定此参数，则只返回ID比since_id大的记录（比since_id发表时间晚）</param>
        /// <param name="max">若指定此参数，则返回ID小于或等于max_id的记录</param>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetMessages(Int64 since_id, Int64 max, int count, int page)
        {
            if (count <= 0)
                count = 20;
            else if (count > 200)
                count = 200;
            if (page <= 0) page = 1;
            string url = @"http://api.t.sina.com.cn/direct_messages.json";
            string para = string.Format("count={0}&page={1}", count, page);
            if (since_id > 0)
                para += "&since_id=" + since_id;
            if (max > 0)
                para += "&max=" + max;
            return OAuth.OAuthWebRequest(Method.GET, url + para, null);
        }

        /// <summary>
        /// 返回用户最新收到的私信，每条私信包含发送者和接受者的详细信息。
        /// </summary>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetMessages(int count, int page)
        {
            return this.GetMessages(-1, -1, count, page);
        }

        /// <summary>
        /// 返回用户最新收到的20条私信，每条私信包含发送者和接受者的详细信息。
        /// </summary>
        /// <returns></returns>
        public string GetMessages()
        {
            string url = @"http://api.t.sina.com.cn/direct_messages.json";
            return OAuth.OAuthWebRequest(Method.GET, url, null);
        }

        #endregion

        #region 提到

        /// <summary>
        /// 返回最新n条提到登录用户的微博消息（即包含@username的微博消息）
        /// </summary>
        /// <param name="since_id">若指定此参数，则只返回ID比since_id大的记录（比since_id发表时间晚）</param>
        /// <param name="max">若指定此参数，则返回ID小于或等于max_id的记录</param>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetMentions(Int64 since_id, Int64 max, int count, int page)
        {
            if (count <= 0)
                count = 20;
            else if (count > 200)
                count = 200;
            if (page <= 0) page = 1;
            string url = @"http://api.t.sina.com.cn/statuses/mentions.json";
            string para = string.Format("count={1}&page={2}", count, page);
            if (since_id > 0)
                para += "&since_id=" + since_id;
            if (max > 0)
                para += "&max=" + max;
            return OAuth.OAuthWebRequest(Method.GET, url + para, null);
        }

        /// <summary>
        /// 返回最新n条提到登录用户的微博消息（即包含@username的微博消息）
        /// </summary>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetMentions(int count, int page)
        {
            return this.GetMessages(-1, -1, count, page);
        }

        /// <summary>
        /// 返回最新20条提到登录用户的微博消息（即包含@username的微博消息）
        /// </summary>
        /// <returns></returns>
        public string GetMentions()
        {
            string url = @"http://api.t.sina.com.cn/statuses/mentions.json";
            return OAuth.OAuthWebRequest(Method.GET, url, null);
        }

        #endregion

        #region 关注相关接口
        /// <summary>
        /// 添加关注
        /// </summary>
        /// <param name="user_id">要关注用户的id</param>
        /// <returns></returns>
        public string CreateFriend(string user_id)
        {
            string url = @"http://api.t.sina.com.cn/friendships/create.json";
            string para = string.Format("user_id ={0}", user_id);
            return OAuth.OAuthWebRequest(Method.POST, url, para, null);
        }

        /// <summary>
        /// 取消关注
        /// </summary>
        /// <param name="user_id">要取消关注用户的id</param>
        /// <returns></returns>
        public string DestroyFriend(string user_id)
        {
            string url = @"http://api.t.sina.com.cn/friendships/destroy.json";
            string para = string.Format("user_id ={0}", user_id);
            return OAuth.OAuthWebRequest(Method.POST, url, para, null);
        }

        /// <summary>
        /// 判断用户a是否关注了用户b，返回示例：{"friends":true}
        /// </summary>
        /// <param name="user_a"></param>
        /// <param name="user_b"></param>
        /// <returns></returns>
        public string IsFriend(string user_a, string user_b)
        {
            string url = string.Format("http://api.t.sina.com.cn/friendships/exists.json?user_a={0}&user_b={1}", user_a, user_b);
            return OAuth.OAuthWebRequest(Method.GET, url, string.Empty);
        }
        #endregion

        #region 用户接口

        /// <summary>
        /// 验证当前用户身份是否合法，通行证成功并开通微博，返回 user
        /// </summary>
        /// <returns></returns>
        public string VerifyCredentials()
        {
            string url = "http://api.t.sina.com.cn/account/verify_credentials.json";
            return OAuth.OAuthWebRequest(Method.GET, url, null, null);
        }

        /// <summary>
        /// 按用户ID返回用户资料以及用户的最新发布的一条微博消息。
        /// </summary>
        /// <returns></returns>
        public string GetUserInfo(string user_id)
        {
            string url = string.Format("http://api.t.sina.com.cn/users/show.json?user_id={0}", user_id);
            return OAuth.OAuthWebRequest(Method.GET, url, null, null);
        }

        /// <summary>
        /// 获取当前登录用户最近发表的微博消息列表
        /// </summary>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetUserTimeline(int count, int page)
        {
            return GetUserTimeline(null, count, page);
        }

        /// <summary>
        /// 根据用户ID获取当前微博用户发布的微博消息列表
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="page">返回结果的页码(默认值1)</param>
        /// <returns></returns>
        public string GetUserTimeline(string user_id, int count, int page)
        {
            string url = string.Format("http://api.t.sina.com.cn/statuses/user_timeline.json?count={0}&page={1}", count, page);
            if (!string.IsNullOrEmpty(user_id))
            {
                url += string.Format("&user_id={0}", user_id);
            }
            return OAuth.OAuthWebRequest(Method.GET, url, null, null);
        }

        /// <summary>
        /// 获取当前登录用户关注列表及每个关注用户的最新一条微博，返回结果(next_cursor字段，表示下一页的cursor)按关注时间倒序排列，最新关注的用户排在最前面。
        /// </summary>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="cursor">分页(-1:返回第一页；0:已经到记录末尾)</param>
        /// <returns></returns>
        public string GetFriends(int count, int cursor)
        {
            return GetFriends(null, count, cursor);
        }

        /// <summary>
        /// 根据用户Id获取用户关注列表及每个关注用户的最新一条微博，返回结果(next_cursor字段，表示下一页的cursor)按关注时间倒序排列，最新关注的用户排在最前面。
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="cursor">分页(-1:返回第一页；0:已经到记录末尾)</param>
        /// <returns></returns>
        public string GetFriends(string user_id, int count, int cursor)
        {
            cursor = Math.Max(-1, cursor);
            count = Math.Max(5, count);
            count = Math.Min(200, count);
            string url = string.Format("http://api.t.sina.com.cn/statuses/friends.json?count={0}&cursor={1}", count, cursor);
            //cursor用于分页请求，请求第1页cursor传-1，在返回的结果中会得到next_cursor字段，表示下一页的cursor。next_cursor为0表示已经到记录末尾。
            if (!string.IsNullOrEmpty(user_id))
            {
                url += string.Format("&user_id={0}", user_id);
            }
            return OAuth.OAuthWebRequest(Method.GET, url, null, null);
        }

        /// <summary>
        /// 获取当前登录用户粉丝列表及每个粉丝的最新一条微博，返回结果(next_cursor字段，表示下一页的cursor)按粉丝的关注时间倒序排列，最新关注的粉丝排在最前面。注意：最多只能返回5000个
        /// </summary>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="cursor">分页(-1:返回第一页；0:已经到记录末尾)</param>
        /// <returns></returns>
        public string GetFollowers(int count, int cursor)
        {
            return GetFollowers(null, count, cursor);
        }

        /// <summary>
        /// 获取用户粉丝列表及每个粉丝的最新一条微博，返回结果(next_cursor字段，表示下一页的cursor)按粉丝的关注时间倒序排列，最新关注的粉丝排在最前面。注意：最多只能返回5000个
        /// </summary>
        /// <param name="user_id">用户ID</param>
        /// <param name="count">单页返回的记录条数(默认值20，最大值200)</param>
        /// <param name="cursor">分页(-1:返回第一页；0:已经到记录末尾)</param>
        /// <returns></returns>
        public string GetFollowers(string user_id, int count, int cursor)
        {
            cursor = Math.Max(-1, cursor);
            count = Math.Max(5, count);
            count = Math.Min(200, count);
            string url = string.Format("http://api.t.sina.com.cn/statuses/followers.json?count={0}&cursor={1}", count, cursor);
            //cursor用于分页请求，请求第1页cursor传-1，在返回的结果中会得到next_cursor字段，表示下一页的cursor。next_cursor为0表示已经到记录末尾。
            if (!string.IsNullOrEmpty(user_id))
            {
                url += string.Format("&user_id={0}", user_id);
            }
            return OAuth.OAuthWebRequest(Method.GET, url, null, null);
        }

        /// <summary>
        /// 获取系统推荐的用户列表。
        /// </summary>
        /// <param name="type">用户类别</param>
        /// <returns></returns>
        public string GetHotUsers(SinaUserType type)
        {
            string category = type.ToString();
            if (category == "def") category = "default";
            string url = string.Format("http://api.t.sina.com.cn/users/hot.json?category={0}", category);
            return OAuth.OAuthWebRequest(Method.GET, url, null, null);
        }

        /// <summary>
        /// 获取当前用户可能感兴趣的用户
        /// </summary>
        /// <returns></returns>
        public string GetSuggestions()
        {
            return GetSuggestions(false);
        }

        /// <summary>
        /// 获取当前用户可能感兴趣的用户
        /// </summary>
        /// <param name="with_reason">是否返回推荐原因</param>
        /// <returns></returns>
        public string GetSuggestions(bool with_reason)
        {
            int reason_type = with_reason ? 1 : 0;
            string url = string.Format("http://api.t.sina.com.cn/users/suggestions.json?with_reason={0}", reason_type);
            return OAuth.OAuthWebRequest(Method.GET, url, string.Empty);
        }

        #endregion

        /// <summary>
        /// 设置OAuth
        /// </summary>
        /// <param name="token"></param>
        /// <param name="secret"></param>
        public void SetOAuth(string token, string secret)
        {
            OAuth.Token = token;
            OAuth.TokenSecret = secret;
        }

        #region IWeiBee Members

        public WeiBoType UserType
        {
            get { return WeiBoType.Sina; }
        }

        public OAuthBase GetOAuth()
        {
            return OAuth;
        }

        #endregion
    }


    /// <summary>
    /// 新浪推荐用户类别
    /// </summary>
    public enum SinaUserType
    {
        def,//人气关注
        ent,//影视名星
        hk_famous,//港台名人
        model,//模特
        cooking,//美食&健康
        sport,//体育名人
        finance,//商界名人
        tech,//IT互联网
        singer,//歌手
        writer,//作家
        moderator,//主持人
        medium,//媒体总编
        stockplayer//炒股高手 
    }
}
